/**
 * ...
 * @author puric
 */

package palmerpuric.tweets2bits;

class Util 
{
	public function new() {}
	/**
	 * Pretvarja string v stevila > charCodeAt (pomeben encoding!)
	 * @param	tweet
	 * @return
	 */
	public function tweet2int(tweet:String) : Array<Int>{
		var res:Array<Int> = new Array<Int>();
		for(i in 0...tweet.length)
			res.push(tweet.charCodeAt(i)); 
		return res;
	}

	/**
	 * Pretvarja iz stevila v string > fromCharCode (pomeben encoding!)
	 * Zaenkrat se ni uporabljeno
	 * @param	num
	 * @return
	 */
	public function int2tweet(num:Array<Int>) : String{
		var res:String = "";
		// greem cez tweet in sestavljam string iz charCodov
		for (i in num)
			res += String.fromCharCode(i) + " "; 
		return res;
	}
	
	/**
	 * Pretvarja stevila v polje stevilk (bitov - le 0 ali 1).
	 * http://en.wikipedia.org/wiki/Binary_numeral_system#Conversion_to_and_from_other_numeral_systems
	 */
	public function int2bitArray(num:Float) : Array<UInt>{
		var bits:Array<UInt> = new Array<UInt>();
		// ker v haXu ne poznam nobenega bit shiftanja ipd bom uporabil algoritem, opisan zgoraj na Wiki-ju
		while ((Math.floor(num / 2)) >= 1){
			if (num % 2 == 0)
				bits.push(0);
			if (num % 2 == 1)
				bits.push(1);
			//trace(num + " " + num % 2); good debug
			num = Math.floor(num / 2);
		}
		if (num == 0)
			bits.push(0);
		if (num == 1)
			bits.push(1);

		bits.reverse();
		return bits;
	}
	
	/**
	 * Iz polja stevilk (bitov) sestavi string - za lepsi izpis
	 * @param	bitArray
	 * @return
	 */
	public function bitArray2String(bitArray:Array<Int>) : String {
		var res:String = "";
			for (i in bitArray)
				res += Std.string(i); // palmer bil tu
		return res;
	}
	
	public function findAndMarkKeywords(markedTweetInBitHash:Hash<Array<UInt>> , tweet:Array<Int>, keyword:Array<Int>) 
	: Hash<Array<UInt>> {
		var keywordInTweet:Array<UInt> = new Array<UInt>();
		
		var i : Int = 0;
		// za vsako crko v tweetu, ki je tu ze stevilka
		while (i < tweet.length) {
			var theSame = 0;
			for (j in 0...keyword.length) {
				if (tweet[i + j] == keyword[j])
					theSame++;
			}
			// ce se ujemajo vsi biti iz keyworda in je za to besedo limiter
			if (theSame == keyword.length && isLimiter(tweet, i + keyword.length)){
				// torej je zadetek od i do i + keyword.length
				for (k in i...(i + keyword.length)) {
					keywordInTweet = int2bitArray(tweet[k]);
					for (bit in 0...keywordInTweet.length) {
						if (keywordInTweet[bit] == 0)
							keywordInTweet[bit] = 2;
						if (keywordInTweet[bit] == 1)
							keywordInTweet[bit] = 3;
					}
					markedTweetInBitHash.set(Std.string(i), keywordInTweet);
					i++;
				}
			}
			// convert to bits
			else {
				// ce na tej poziciji se ni bitov, jih dodam, sicer so najbrz ze oznaceni
				if (!markedTweetInBitHash.exists(Std.string(i)))
					markedTweetInBitHash.set(Std.string(i), int2bitArray(tweet[i]));
				i++;
			}
		}
		return markedTweetInBitHash;
	}
	
	function isLimiter(tweet:Array<Int>, index:Int) : Bool {
		// ce je konec tweeta je limiter tudi true
		if (tweet[index] == 0)
			return true;
		// ce ni zacetek tweeta oz. eno od locil: presledek, klicaj, vejica, ...
		// glej http://www.tony-franks.co.uk/UTF-8.htm
		if ((tweet[index] > 31  && tweet[index] < 48) 
		  ||(tweet[index] > 90  && tweet[index] < 97)
		  ||(tweet[index] > 57  && tweet[index] < 65)
		  ||(tweet[index] != 142 && tweet[index] > 122  && tweet[index] < 192)) // 142 = false
			return true;
		else
			return false;
	}
	
	public function removeNewLines(tweet:String) : String {
		var res:StringBuf = new StringBuf();
		// ker je lahko newlinov poljubno grem cez cel tweet
		for (i in 0...tweet.length) {
			if (tweet.charAt(i) != '\n')
				res.add(tweet.charAt(i));
			else
				res.add(" ");
		}
		return res.toString();
	}
}